#pragma once

#include <boost/shared_ptr.hpp>
#include <map>
#include "utils.h"

namespace Broady {

class Socket;

class External
{
	typedef std::pair<unsigned long, unsigned short> IPPortPair;
	typedef std::map< IPPortPair, boost::shared_ptr<client_t> > ClientPtrList;

public:
	External( void );
	~External( void );

	bool IsLocalNode( unsigned short port ) const;
	bool IsInit( void ) const;
	bool Init( unsigned int addr );
	bool Step( void );
	void Quit( void );
	bool SendPacket( boost::shared_ptr<client_t> client, const unsigned char* packet, unsigned int plen, unsigned short port );
	bool Incoming( const unsigned char* packet, unsigned int len );

private:
	boost::shared_ptr<client_t> GetClient( unsigned long ip, unsigned short port );
	boost::shared_ptr<client_t> AddClient( unsigned long ip, unsigned short port );
	bool DelClient( unsigned long ip, unsigned short port );
	bool SendPing( boost::shared_ptr<client_t> client, unsigned int id );
	bool SendBroadcast( boost::shared_ptr<client_t> client, const unsigned char* packet, unsigned int plen, unsigned short port );
	bool SendGoodbye( boost::shared_ptr<client_t> client );
	bool SendShake( unsigned int id, unsigned long ip, unsigned short port );
	bool OnShake( unsigned char* packet, unsigned int len, unsigned long ip, unsigned short port );
	bool OnBroadcast( unsigned char* packet, unsigned int len, unsigned long ip, unsigned short port );
	bool OnPing( unsigned char* packet, unsigned int len, unsigned long ip, unsigned short port );
	bool OnData( unsigned char* packet, unsigned int len, unsigned long ip, unsigned short port );
	bool OnQuit( unsigned char* packet, unsigned int len, unsigned long ip, unsigned short port );
	bool Parse( boost::shared_ptr<unsigned char> packet, unsigned int len, unsigned long ip, unsigned short port );
	bool Read( void );

private:
	bool m_init;
	ip_address m_ip;
	unsigned short m_port;
	boost::shared_ptr<Socket> m_sck;
	ClientPtrList m_clients;
};

} // namespace
